//
// Created by jack on 2021/2/6.
//

#include "weilapb_defines.h"

#include <WL.Service.pb.h>
#include <WL.System.pb.h>
#include <pb_decode.h>

#include "weilapb_datafuns.h"

#include "weilapb_error.h"
#include "weilapb_internal.h"
#include "weilapb_system.h"

PBWeilaMsg* weilapb_decodeNotificationNtf(const PB_UINT8* pData, PB_UINT32 dataSize) {
    WL_Service_ServiceMessage serviceMessage = WL_Service_ServiceMessage_init_zero;
    pb_istream_t              istream;
    PB_CHAR*                  pContent;
    PBWeilaMsg*               pWeilaMsg = PB_NULL;

    istream  = pb_istream_from_buffer(pData, dataSize);
    pContent = (PB_CHAR*)PB_ALLOC(MAX_NORMAL_STRING_LEN * sizeof(PB_CHAR));
    if (pContent) {
        PBFieldData contentField;
        PBWeilaMsg  pbWeilaMsg;
        memset(&pbWeilaMsg, 0, sizeof(PBWeilaMsg));
        weilapb_initDecDataItem(&contentField, PB_DATA_TYPE_DYNAMIC_STRING, MAX_NORMAL_STRING_LEN, pContent);
        weilapb_setDecCallback(&contentField, &serviceMessage.systemMessage.ntfNotification.content, PB_NULL);

        if (weilapb_decodeWeilaMsg(&pbWeilaMsg, &istream, &serviceMessage)) {
            PBWeilaMsg* pWeilaMsg = PB_ALLOC(sizeof(PBWeilaMsg) + sizeof(PBString) + contentField.dataSize + 1);
            if (pWeilaMsg) {
                PBString* pPbString;
                pbWeilaMsg.contentSize = sizeof(PBString) + contentField.dataSize + 1;
                memcpy(pWeilaMsg, &pbWeilaMsg, sizeof(PBWeilaMsg));
                pPbString         = (PBString*)pWeilaMsg->pContent;
                pPbString->strLen = contentField.dataSize;
                memcpy(pPbString->str, contentField.pData, strlen(contentField.pData));
                if (NULL != contentField.pData) {
                    PB_FREE(contentField.pData);
                }
                PB_FREE(pContent);
                return pWeilaMsg;
            } else {
                weilapb_error(ERR_OUT_OF_MEMORY, "allocate weila msg failed");
            }
        } else {
            weilapb_error(ERR_DECODE, "decode msg data fail");
        }

        PB_FREE(pContent);
    } else {
        weilapb_error(ERR_OUT_OF_MEMORY, "allocate weila msg failed");
    }

    return pWeilaMsg;
}

PBWeilaMsg*
    weilapb_decodeSystemMsg(PB_INT32 commandId, PB_INT32 commandType, const PB_UINT8* pData, PB_UINT32 dataSize) {
    PBWeilaMsg* pPbWeilaMsg = PB_NULL;
    switch (commandId) {
        case WL_System_SystemCommandId_SYSTEM_COMMAND_NOTIFICATION: {
            pPbWeilaMsg = weilapb_decodeNotificationNtf(pData, dataSize);
            if (pPbWeilaMsg) {
                pPbWeilaMsg->message = WL_SYSTEM_NOTIFICATION_MSG;
            }
        } break;
    }

    return pPbWeilaMsg;
}
